const { app, BrowserWindow, globalShortcut, Menu, dialog, ipcMain, shell, remote } = require('electron')
const Tesseract = require('tesseract.js')
const fs = require('fs')
const xlsx = require('xlsx')
const moment = require('moment/moment')
const Utils = require('./src/lib/utils')
const path = require('path')
const baseDir = path.join(__dirname, 'src')
const viewDir = path.join(baseDir, 'view')
const nodeModule = {nodeIntegration: true}
const remoteModule = {enableRemoteModule: true}
const preloadEnable = {...nodeModule, ...remoteModule}
const cxtIso = {contextIsolation: false}
const viewUseNode = {...preloadEnable, ...cxtIso}

let mainWindow
function createWindow (pageName, otherWebPreferences = {}) {
  mainWindow = new BrowserWindow({
    width: 800, height: 680,
    minWidth: 760, minHeight: 460,
    webPreferences: {
      preload: path.join(viewDir, `js/${pageName}.js`),
      ...otherWebPreferences
    }
  })
  mainWindow.loadURL(`${viewDir}/${pageName}.html`)
  mainWindow.webContents.openDevTools() // todo
}
ipcMain.on('btnSelectDirClick', (ev,data) => {
  dialog.showOpenDialog(mainWindow, {
    properties: ['openDirectory']
  }).then(result => {
    const channel = result.canceled ? 'selectDirCancel' : 'selectDirSubmit';
    ev.sender.send(channel, result.filePaths)
  }).catch(err => {
    ev.sender.send('selectDirErr', [])
  })
})
ipcMain.on('btnSelectFileClick', (ev,data) => {
  dialog.showOpenDialog(mainWindow, {
    filters: [
      { name: 'Excel', extensions: ['xlsx'] }
    ],
    properties: ['openFile']
  }).then(result => {
    const channel = 'selectExcelFile';
    ev.sender.send(channel, result.filePaths)
  }).catch(err => {
    ev.sender.send('selectExcelFile', [])
  })
})
ipcMain.on('openFile', (ev,data) => {
  shell.openPath(data)
})
ipcMain.on('showItemInFolder', (ev,data) => {
  shell.showItemInFolder(data)
})
const evtName = 'doingInfoRes'
// 执行读取匹配任务
ipcMain.on('doTask', async (ev,data) => {
  const infoArr = []
  let doingInfoObj = {imgPrg: 0, filePrg: 0, dataMatchPrg: 0, info: '', errNo: 0, msg: '', allDone: 0}
  Utils.observer(doingInfoObj, () => {ev.sender.send(evtName, doingInfoObj)})
  try {
    setSoingInfoObj(doingInfoObj, infoArr, `开始[${moment().format('HH:mm:ss')}]...`)
    const {dir, file} = data
    let prgPercentage = 0
    setSoingInfoObj(doingInfoObj, infoArr, `图片处理: ${prgPercentage}%`)
    const files = fs.readdirSync(dir)
    const fileCount = files.length
    let doneCount = 0
    setSoingInfoObj(doingInfoObj, infoArr, `图片处理: ${prgPercentage}%，文件总数 ${fileCount}，已处理数 ${doneCount}`)
    const imgInfoObj = {}
    // 图片读取
    const worker = await Tesseract.createWorker('chi_sim', {langPath: './'})
    await worker.setParameters({
        tessedit_char_whitelist: '0123456789',
    })
    for(const item of files) {
      const imagePath = path.join(dir, item);
      if (fs.statSync(imagePath).isFile()) {
        const fileFix = item.substr(item.lastIndexOf('.') + 1)
        if (['png', 'jpg'].includes(fileFix.toLocaleLowerCase())) {
          const ret = await worker.recognize(imagePath)
          const arr  = ret.data.text.split('\n').map((v) => v.replaceAll(' ', '')).filter((v) => {return /^\d{8}$/.test(v) || /^\d{11}$/.test(v)})
          const arrLen = arr.length
          if (arrLen >= 2) {
            let mobile = ''
            let no4 = ''
            const lastMember = arr[arrLen - 1]
            const lastSecondMember = arr[arrLen - 2]
            if (lastMember.length === 11) {
              mobile = lastMember
            } else if (lastMember.length === 8) {
              no4 = lastMember.substr(-4)
            }
            if (lastSecondMember.length === 11) {
              mobile = lastSecondMember
            } else if (lastSecondMember.length === 8) {
              no4 = lastSecondMember.substr(-4)
            }
            if (imgInfoObj.hasOwnProperty(no4)) {
              Object.assign(imgInfoObj, {[no4]: `${imgInfoObj[no4]},${mobile}`})
            } else {
              Object.assign(imgInfoObj, {[no4]: mobile})
            }
          }
        }
      }
      doneCount ++
      prgPercentage = Math.floor(doneCount * 100 / fileCount)
      doingInfoObj.imgPrg = prgPercentage
      setSoingInfoObj(doingInfoObj, infoArr, `图片处理: ${prgPercentage}%，文件总数 ${fileCount}，已处理数 ${doneCount}`)
    }
    await worker.terminate()
    Object.assign(doingInfoObj, {imgPrg: 100})

    prgPercentage = 0
    setSoingInfoObj(doingInfoObj, infoArr, `Excel读取: ${prgPercentage}%`)
    const workbook = xlsx.readFile(file)
    prgPercentage = 60
    setSoingInfoObj(doingInfoObj, infoArr, `Excel读取: ${prgPercentage}%`)
    Object.assign(doingInfoObj, {filePrg: prgPercentage})
    const sheetName = workbook.SheetNames[0]
    const sheet = workbook.Sheets[sheetName]
    const xlsxData = xlsx.utils.sheet_to_json(sheet, { header: 1 })
    prgPercentage = 100
    setSoingInfoObj(doingInfoObj, infoArr, `Excel读取: ${prgPercentage}%，Excel表格总行数: ${xlsxData.length}`)
    Object.assign(doingInfoObj, {filePrg: prgPercentage})
    const flagColumn = '快递单号'
    let addColumn = '电话号码'
    let addIndex = -1
    let flagIndex = -1
    let flagIndex1 = 1
    let last4str = ''
    let currRow = []
    prgPercentage = 0
    setSoingInfoObj(doingInfoObj, infoArr, `数据匹配: 开始...`)
    Object.assign(doingInfoObj, {dataMatchPrg: prgPercentage})
    const xlsxDataCount = xlsxData.length - 1
    for(const index in xlsxData) {
      currIndex = parseInt(index, 10) + 1
      currRow = xlsxData[index].map((v) => `${v}`)
      // console.log(currRow) // todo
      // console.log('index--', index) // todo
      if (index == 0) {
        flagIndex = xlsxData[index].indexOf(flagColumn)
        // console.log('flagIndex--', flagIndex) // todo
        if (flagIndex === -1) {
          break;
        }
        flagIndex1 = flagIndex + 1
        addIndex = xlsxData[index].indexOf(addColumn)
      } else {
        if (!currRow[flagIndex]) {
          continue
        }
        last4str = currRow[flagIndex].trim().substr(-4)
        if (last4str === '') {
          continue;
        }
        addColumn = imgInfoObj.hasOwnProperty(last4str) ? imgInfoObj[last4str] : ''
      }
      if (addIndex === -1) {
        const arr0 = currRow.slice(0, flagIndex1)
        const arr1 = currRow.slice(flagIndex1)
        xlsxData[index] = [...arr0, addColumn, ...arr1]
      } else {
        if (addColumn) {
          xlsxData[index][addIndex] = addColumn
        }
      }
      setSoingInfoObj(doingInfoObj, infoArr, `${index} / ${xlsxDataCount} ${currRow[flagIndex]} - ${addColumn}`)
      prgPercentage = Math.floor(index * 100 / xlsxDataCount)
      Object.assign(doingInfoObj, {dataMatchPrg: prgPercentage})
    }
    prgPercentage = 100
    Object.assign(doingInfoObj, {dataMatchPrg: prgPercentage})
    if (flagIndex === -1) {
      const msg = 'Excel表中未发现“快递单号”列'
      setSoingInfoObj(doingInfoObj, infoArr, `ERR: ${msg}`)
      Object.assign(doingInfoObj, {errNo: 1, msg})
    } else {
      setSoingInfoObj(doingInfoObj, infoArr, `数据匹配: 完成`)
    }

    // 写入Excel文件
    setSoingInfoObj(doingInfoObj, infoArr, `生成Excel表格: 开始...`)
    const newWorkbook = xlsx.utils.book_new()
    const newSheet = xlsx.utils.aoa_to_sheet(xlsxData, {raw:true})
    xlsx.utils.book_append_sheet(newWorkbook, newSheet, sheetName)
    const basePath = path.resolve('data')
    const exists = await FsAction.getStat(basePath)
    if (!exists) {
      fs.mkdirSync(basePath, { recursive: true })
    }
    const currTime = moment().format('YYYYMMDD_HHmmss')
    const filePath = path.resolve('data', `${file.substring(file.lastIndexOf('\\') + 1, file.lastIndexOf('.'))}_${currTime}.xlsx`)
    xlsx.writeFile(newWorkbook, filePath)
    setSoingInfoObj(doingInfoObj, infoArr, `生成Excel表格: 完成`)
    setSoingInfoObj(doingInfoObj, infoArr, `Excel文件: ${filePath}`)
    setSoingInfoObj(doingInfoObj, infoArr, `全部完成: ${moment().format('HH:mm:ss')}`)
    Object.assign(doingInfoObj, {filePath})
    Object.assign(doingInfoObj, {allDone: 1})
  } catch (err) {
    console.log(err) // todo
    const msg = JSON.stringify(err)
    setSoingInfoObj(doingInfoObj, infoArr, `ERR: ${msg}`)
    Object.assign(doingInfoObj, {errNo: 100, msg: '程序错误'})
  }
})
app.whenReady().then(() => {
  createWindow('home', preloadEnable)
  // Menu.setApplicationMenu(null) // todo
  app.on('ready', () => {
    if (process.platform === 'win32') {
      app.setAppUserModelId("com.ikobit.desktop-notifications");
    }
  })
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
  app.on('will-quit', () => {
  })
})

app.on('window-all-closed', () => {
    // 注销所有快捷键
    globalShortcut.unregisterAll()
  if (process.platform !== 'darwin') app.quit()
})

function setSoingInfoObj(obj, infoArr, arrItem, index) {
  if (!! index) {
    infoArr[index] = arrItem
  } else {
    infoArr.push(arrItem)
  }
  Object.assign(obj, {info: infoArr.join("\n")})
}
const FsAction = {
  /**
 * 读取路径信息
 * @param {string} path 路径
 */
  getStat: async (dir) => {
    try {
    const stat = await fs.stat(dir);
      return stat
    } catch (error) {
      return false
    }
  }
}
